package com.youlu.campus.service.ca.impl;

import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.*;
import com.youlu.campus.entity.VO.req.CaGrantQuery;
import com.youlu.campus.entity.VO.req.CreateCaGrantReq;
import com.youlu.campus.entity.VO.res.CaGrantRes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CaGrantService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private CaCollectService caCollectService;


    public void saveOrUpdate(CreateCaGrantReq createCaGrantReq){
        String id = createCaGrantReq.getId();
        CaGrant caGrant = null;
        if(StringUtils.isNotBlank(id)){
            caGrant = mongoTemplate.findById(id, CaGrant.class);
            if(!caGrant.getStatus().equals(CaGrant.un_grant)){
                throw new BusinessException("未在待发放状态，不能编辑");
            }
            caGrant.setUpdatedTime(new Date());
        }else{
            caGrant = new CaGrant();
            caGrant.setCreatedTime(new Date());
        }
        String caTemplateId = createCaGrantReq.getCaTemplateId();
        CaTemplate caTemplate = mongoTemplate.findById(caTemplateId, CaTemplate.class);
        if(Objects.isNull(caTemplate)){
            throw new BusinessException("证书模版不存在");
        }
       // caGrant.setCaLevel(caTemplate.getCaLevel());
        caGrant.setCaName(caTemplate.getCaName());
        caGrant.setCaTemplate(caTemplate);
        caGrant.setActivityId(createCaGrantReq.getActivityId());
        caGrant.setActivityName(createCaGrantReq.getActivityName());
        mongoTemplate.save(caGrant);
    }

    public void caGrant(String grantId){
        CaGrant caGrant =  mongoTemplate.findById(grantId, CaGrant.class);
        if(!caGrant.getStatus().equals(CaGrant.un_grant)){
            throw new BusinessException("未在待发放状态，不能进行发放");
        }
        caGrant.setUpdatedTime(new Date());
        caGrant.setStatus(CaGrant.grant);
        this.mongoTemplate.save(caGrant);
        log.info(" start grant ca ");
        CaTemplate caTemplate = caGrant.getCaTemplate();
      //  String activityId = caTemplate.getActivityId();
      //  String caLevel = caTemplate.getCaLevel();
        Query query = new Query();
       // query.addCriteria(Criteria.where("activityId").is(activityId));
       // query.addCriteria(Criteria.where("caLevel").is(caLevel));
        query.addCriteria(Criteria.where("certificateEnable").is(Boolean.FALSE));
        log.info("【电子证书发放】活动名称 - > {} 证书等级 - > {} 未开放可用的",caGrant.getActivityName());
        while (true){
            query.limit(1000);
            List<CaCertificateLog> caList = this.mongoTemplate.find(query, CaCertificateLog.class);
            if(CollectionUtils.isEmpty(caList)){
                break;
            }
            Update update = new Update();
            update.set("certificateEnable",Boolean.TRUE);
            update.set("updatedTime",new Date());
            this.mongoTemplate.updateMulti(query,update,CaCertificateLog.class);
            caList.stream().forEach(caCert ->{
                String certificateNo = caCert.getCertificateNo();
                String userId = caCert.getUserId();
                UserParticipateActivityInfo userParticipateActivity = caCollectService.getUserParticipateActivity(userId, "");
                caCollectService.caBuild(certificateNo,null,caTemplate);
            });
        }
    }

    public Page<CaGrantRes> list (CaGrantQuery caGrantQuery){
        Query query = new Query();
        String activityName = caGrantQuery.getActivityName();
        if(StringUtils.isNotBlank(activityName)){
            Pattern pattern = Pattern.compile("^.*" + activityName + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("activityName").regex(pattern));
        }
        String caName = caGrantQuery.getCaName();
        if(StringUtils.isNotBlank(caName)){
            Pattern pattern = Pattern.compile("^.*" + caName + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("caName").regex(pattern));
        }
        String status = caGrantQuery.getStatus();
        if(StringUtils.isNotBlank(status)){
            query.addCriteria(Criteria.where("status").is(status));
        }
        PageRequest pageRequest = PageRequest.of(caGrantQuery.getPageNo() - 1, caGrantQuery.getPageSize());
        long count = this.mongoTemplate.count(query, CaGrant.class);
        if(count==0){
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<CaGrant> list = this.mongoTemplate.find(query.with(pageRequest), CaGrant.class);
        List<CaGrantRes> caGramtResList = list.stream().map(caGrant -> {
            CaGrantRes caGrantRes = new CaGrantRes();
            caGrantRes.setId(caGrant.getId());
            caGrantRes.setActivityId(caGrant.getActivityId());
            caGrantRes.setActivityName(caGrant.getActivityName());
            caGrantRes.setCaLevel(caGrant.getCaLevel());
            caGrantRes.setStatus(caGrant.getStatus());
            caGrantRes.setCaName(caGrant.getCaName());
            return caGrantRes;
        }).collect(Collectors.toList());
        return PageableExecutionUtils.getPage(caGramtResList, pageRequest, () -> count);
    }
}
